﻿using FrameworkCore.Modules.Startups;
using FrameworkCore.Mvc;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using NM.Module.Auth.API.Configurations;
using NM.Module.Auth.API.Handlers;
using System.Text;

namespace NM.Module.Auth.API;

/// <summary>
/// 登录管理
/// </summary>
public partial class NetModulerStartup : INetModulerStartup, IRouteProvider
{
    public int Order => 899;//在加载MVC之前加载

    public int Priority => Order;

    public void Configure(IApplicationBuilder application)
    {
        application.UseAuthentication();
        application.UseAuthorization();
    }

    public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
    {
        var config = ConfigurationsExtensions.AddJsonFile("auth");
        services.Configure<JwtSettings>(config.GetSection(JwtSettings.Key));

        #region 授权认证
        JwtSettings jwtSettings = config.GetSection(JwtSettings.Key).Get<JwtSettings>()!;
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddAuthorization();
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = nameof(ResponseAuthenticationHandler); //401
            options.DefaultForbidScheme = nameof(ResponseAuthenticationHandler);    //403
        }).AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new()
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = jwtSettings.Issuer,
                ValidAudience = jwtSettings.Audience,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecurityKey)),
                ClockSkew = TimeSpan.FromSeconds(0)
            };
            options.Events = new JwtBearerEvents
            {
                OnMessageReceived = context =>
                {
                    var accessToken = context.Request.Query["access_token"];
                    // If the request is for our hub...
                    var path = context.HttpContext.Request.Path;
                    if (!string.IsNullOrEmpty(accessToken) &&
                        (path.StartsWithSegments("/signalr/hub")))
                    {
                        // Read the token out of the query string
                        context.Token = accessToken;
                    }
                    return Task.CompletedTask;
                }
            };
        }).AddScheme<AuthenticationSchemeOptions, ResponseAuthenticationHandler>(nameof(ResponseAuthenticationHandler), o => { });
        #endregion
    }

    public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
    {
            endpointRouteBuilder
            .MapControllers()
            .RequireAuthorization();
    }
}
